﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.NetworkInformation;
using System.Threading;
using System.Net;

namespace NetAvailMon
{
    public enum NetworkStatus
    {
        Red,
        Yellow,
        Green
    }

    public partial class Form1 : Form
    {
        public bool ShowNotifications { get; set; }

        delegate void SetFormIconCallback(Icon image);
        delegate void AddNotification(string text);

        public Form1()
        {
            InitializeComponent();
            NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
            NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
        }

        private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            //notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
            //notifyIcon1.BalloonTipTitle = "Network addresse changed";
            //notifyIcon1.ShowBalloonTip(5000);
        }

        private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            CheckNetworkAvailible();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //MenuItem toggleNotification = new MenuItem { Name = "toggleNotification", Text = "Toggle notifications", Checked = true };
            //toggleNotification.Click +=new EventHandler(toggleNotification_Click);

            //notifyIcon1.ContextMenu.MenuItems.Add(toggleNotification);
            ShowNotifications = true;
            notifyIcon1.Icon = Properties.Resources.Red;

            CheckNetworkAvailible();
        }

        void toggleNotification_Click(object sender, EventArgs e)
        {
            if (toggleNotifikationsToolStripMenuItem.CheckState == CheckState.Checked)
                ShowNotifications = true;
            else
                ShowNotifications = false;
        }

        private void CheckNetworkAvailible()
        {
            if (NetworkInterface.GetIsNetworkAvailable())
                StartPing();
            else
                SetNetworkStatus(NetworkStatus.Red);
        }

        private void StartPing()
        {
            // Get an object that will block the main thread.
            AutoResetEvent waiter = new AutoResetEvent(false);

            // Ping's the local machine.
            Ping pingSender = new Ping();

            pingSender.PingCompleted += new PingCompletedEventHandler(pingSender_PingCompleted);

            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);

            // Wait 10 seconds for a reply.
            int timeout = 5000;

            PingOptions options = new PingOptions(64, true);

            pingSender.SendAsync("www.google.com", timeout, buffer, options, waiter);

            //if (pingSender.Send("www.google.com", timeout, buffer, options).Status == IPStatus.Success)
            //    SetNetworkStatus(NetworkStatus.Green);
            //else
            //    SetNetworkStatus(NetworkStatus.Yellow);
        }

        private void pingSender_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            if (e.Reply.Status == IPStatus.Success)
                SetNetworkStatus(NetworkStatus.Green);
            else
                SetNetworkStatus(NetworkStatus.Yellow);
        }

        private void SetNetworkStatus(NetworkStatus status)
        {
            switch (status)
            {
                case NetworkStatus.Yellow:
                    NotifyUser("Network is available, but cannot ping google.com",
                        "There is no connection to the internet",
                        ToolTipIcon.Warning,
                        Properties.Resources.Yellow);
                    break;
                case NetworkStatus.Green:
                    NotifyUser("Network is available",
                        "There is connection to the internet",
                        ToolTipIcon.Info,
                        Properties.Resources.Green);
                    break;
                case NetworkStatus.Red:
                default:
                    NotifyUser("Network is not available",
                        "There is no network connection",
                        ToolTipIcon.Warning,
                        Properties.Resources.Red);
                    break;
            }
        }

        private void SetFormIcon(Icon image)
        {
            this.Icon = image;
        }

        private void NotifyUser(string notificationTitle, string notificationText, ToolTipIcon toolTipIcon, Icon image)
        {
            if (this.InvokeRequired)
            {
                SetFormIconCallback d = new SetFormIconCallback(SetFormIcon);
                this.Invoke
                    (d, new object[] { image });
            }
            else
            {
                this.Icon = image;
            }

            notifyIcon1.Icon = image;
            //this.Icon = image;
            notifyIcon1.BalloonTipIcon = toolTipIcon;
            notifyIcon1.BalloonTipTitle = notificationTitle;
            notifyIcon1.BalloonTipText = notificationText;

            if (this.listBox1.InvokeRequired)
            {
                AddNotification d = new AddNotification(Notify);
                this.Invoke
                    (d, new object[] { notificationText });
            }
            else
            {
                Notify(notificationText);
            }


            if (ShowNotifications)
                notifyIcon1.ShowBalloonTip(5000);
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
        }


        private void Notify(string notificationText)
        {
            listBox1.Items.Insert(0, DateTime.Now.ToString("hh:mm:ss ") + notificationText);
            MaintainList();
        }

        private void MaintainList()
        {
            while (listBox1.Items.Count > 10)
            {
                listBox1.Items.RemoveAt(listBox1.Items.Count - 1);
            }
        }
    }
}
